from usuario import Usuario, db_session
from proyecto import Proyecto
from comite import Comite
from item import Item
from estadoItem import EstadoItem
from fase import Fase
from sqlalchemy import exc, or_
from flask import flash
session = db_session()

class ItemManager(object):
    """Clase encargada del manejo de items"""
    def __init__(self):
        pass
    def __repr__(self):
        return '<Item Manager>'
    
    def guardarItem(self, item):
        """
        Metodo encargado de almacenar un item en la base de datos
        @param item: Objeto item que se desea almacenar.
        """
        session.add(item)
        try:
            session.commit()
        except exc.IntegrityError as ex:
            session.rollback()
            return flash("El item ya existe", "error")
        else:
            return flash("Item registrado exitosamente")
        
    def eliminarItem(self, iditem):
        """
        Metodo encargado de eliminar un item de la base de datos
        @param iditem: id del item que se desea eliminar.
        """
        item = session.query(Item).filter(Item.iditem==iditem).first()
        session.delete(item)
        session.commit()
        
    def getItem(self, iditem):
        """
        Metodo encargado de retornar un item de la base de datos
        @param iditem: id del item que se desea obtener.
        """
        item = session.query(Item).filter(Item.iditem==iditem).first()
        return item

    def getItemLB(self, idlineabase):
        """
        Metodo encargado de retornar una lista de items de una linea base de la base de datos
        @param idlineabase: id de la linea base cuyos items se desean obtener.
        """
        items = session.query(Item).\
        filter(Item.idestadoitem!=5).filter(Item.idlineabase==idlineabase).order_by(Item.nombre).all()
        return items
    
    def getItems(self):
        """Metodo encargado de retornar todos los items de la base de datos"""
        items = session.query(Item).\
        filter(Item.idestadoitem!=5).order_by(Item.nombre).all()
        return items
    
    def getItemFiltradoPorNombre(self, nombre):
        """
        Metodo encargado de retornar un item dado su nombre
        @param nombre: nombre del item que se desea obtener.
        """
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"
        item = session.query(Item).\
        filter(Item.idestadoitem!=5).filter(Item.nombre.like(nombre)).order_by(Item.nombre)
        return item
    
    def getItemPorNombre(self, nombre):
        """
        Metodo encargado de retornar un item dado su nombre
        @param nombre: nombre del item que se desea obtener.
        """
        nombre = session.query(Item).filter(Item.nombre==nombre).\
        filter(Item.idestadoitem!=5).order_by(Item.nombre).first()
        return nombre
    
    def getItemsPorFase(self, idfase):
        """
        Metodo encargado de retornar un item dado su idfase
        @param idfase: id de la fase cuyos items se desean obtener.
        """
        items = session.query(Item).filter(Item.idfase==idfase).\
        filter(Item.idestadoitem!=5).\
        filter(Item.idlineabase==None).order_by(Item.nombre).all()
        return items
    
    def getItemsPorFaseOrderId(self, idfase):
        """
        Metodo encargado de retornar un item dado su idfase ordenados por id del item.
        @param idfase: id de la fase cuyos items se desean obtener.
        """
        items = session.query(Item).filter(Item.idfase==idfase).\
        filter(Item.idestadoitem!=5).order_by(Item.iditem).all()
        return items
    
#     def getItemsPorProyecto(self, idproyecto):
#         """Metodo encargado de retornar un item dado su idfase"""
#         items = session.query(Item).filter(Item.idfase==idfase).\
#         filter(Item.idestadoitem!=5).\
#         filter(Item.idlineabase==None).all()
#         return items
    
    def getItemPaginado(self, idfase, nombre, desde, hasta):
        """
        Metodo encargado de retornar un item dada la fase
        @param idfase: id de la fase cuyos items se desean obtener.
        @param nombre: nombre del item que se desea obtener.
        @param desde: indica inicio.
        @param hasta: indica fin.
        """
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"
#si se le pase una idfase obtiene los items de una fase
        if idfase== None:
            if desde != None and hasta != None:
                items = session.query(Item).\
                filter(Item.idestadoitem!=5).\
                filter(Item.nombre.like(nombre)).order_by(Item.nombre)[desde:hasta]
                return items
            else:
                total = session.query(Item).\
                filter(Item.idestadoitem!=5).\
                filter(Item.nombre.like(nombre)).count()
                return total

        else:
            if desde != None and hasta != None:
                items = session.query(Item).filter(Item.idfase==idfase).\
                filter(Item.idestadoitem!=5).\
                filter(Item.nombre.like(nombre)).order_by(Item.nombre)[desde:hasta]
                return items
            else:
                total = session.query(Item).filter(Item.idfase==idfase).\
                filter(Item.idestadoitem!=5).\
                filter(Item.nombre.like(nombre)).count()
                return total
            
    def getItemsDelProyectoPaginado(self, idproyecto, nombre, desde, hasta):
        """
        Metodo encargado de retornar un item dado el proyecto
        @param idproyecto: id del proyecto cuyos items se desean obtener.
        @param nombre: nombre del item que se desea obtener.
        @param desde: indica inicio.
        @param hasta: indica fin.
        """
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"
#si se le pase una idfase obtiene los items de una fase

        if desde != None and hasta != None:
            items = session.query(Item).join(Fase).join(Proyecto).\
            filter(Proyecto.idproyecto== idproyecto).\
            filter(Item.idestadoitem!=5).\
            filter(Item.nombre.like(nombre)).order_by(Item.nombre)[desde:hasta]
            return items
        else:
            total = session.query(Item).join(Fase).join(Proyecto).\
            filter(Proyecto.idproyecto== idproyecto).\
            filter(Item.idestadoitem!=5).\
            filter(Item.nombre.like(nombre)).count()
            return total
    
    def getItemsDelProyecto(self,idproyecto):
        """
        Metodo encargado de retornar items dado el idproyecto
        @param idproyecto: id del proyecto cuyos items se desean obtener. 
        """
        items = session.query(Item).join(Fase).join(Proyecto).\
        filter(Proyecto.idproyecto== idproyecto).\
        filter(Item.idestadoitem!=5).order_by(Item.nombre).all()
        return items
    
    def getNumeroItemDelProyecto(self, idproyecto, idtipoitem):
        item= session.query(Item).join(Fase).join(Proyecto).\
        filter(Proyecto.idproyecto== idproyecto).\
        filter(Item.idtipoitem== idtipoitem).\
        order_by(Item.numeroitem.desc()).distinct().count()
        return item + 1
        
    def getItemsEliminadoDelProyecto(self,idproyecto, nombre, desde, hasta):
        """
        Metodo encargado de retornar los items eliminados de un proyecto
        @param idproyecto: id del proyecto cuyos items se desean obtener.
        @param nombre: nombre del item que se desea obtener.
        @param desde: indica inicio.
        @param hasta: indica fin.
        """
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"
#si se le pase una idfase obtiene los items de una fase

        if desde != None and hasta != None:
            items = session.query(Item).join(Fase).join(Proyecto).\
            filter(Proyecto.idproyecto== idproyecto).\
            filter(Item.idestadoitem==5).\
            filter(Item.nombre.like(nombre)).order_by(Item.nombre)[desde:hasta]
            return items
        else:
            total = session.query(Item).join(Fase).join(Proyecto).\
            filter(Proyecto.idproyecto== idproyecto).\
            filter(Item.idestadoitem==5).\
            filter(Item.nombre.like(nombre)).count()
            return total

    def getItemsEnSCPaginado(self,idfase, idusuario, nombre, desde, hasta):
        """
        Metodo encargado de retornar los items de una fase que se encuentran en una solicitud de cambio
        @param idfase: id de la fase cuyos items se desean obtener.
        @param idusuario: id del usuario que desea listar los items en solicitud.
        @param nombre: nombre del item que se desea obtener.
        @param desde: indica inicio.
        @param hasta: indica fin.
        """
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"

        if desde != None and hasta != None:
            items = session.query(Item).join(Fase).join(Proyecto).\
            filter(Fase.idfase== idfase).\
            filter(Item.idusuariohabilitado==idusuario).\
            filter(Item.nombre.like(nombre)).order_by(Item.nombre)[desde:hasta]
            return items
        else:
            total = session.query(Item).join(Fase).join(Proyecto).\
            filter(Fase.idfase== idfase).\
            filter(Item.idusuariohabilitado==idusuario).\
            filter(Item.nombre.like(nombre)).count()
            return total
        
    def getItemsParaRelacionPaginado(self,idproyecto, nroFase, nombre, desde, hasta):
        """Metodo encargado de retornar un item dado su nombre"""
        if nombre == "":
            nombre = "%"
        else:
            nombre = "%"+nombre+"%"
    #si se le pase una idfase obtiene los items de una fase
    
        if desde != None and hasta != None:
            items = session.query(Item).join(Fase).join(Proyecto).\
            filter(Proyecto.idproyecto== idproyecto).\
            filter(or_(nroFase-Fase.numero==1, nroFase - Fase.numero == 0)).\
            filter(Item.idestadoitem!=5).\
            filter(Item.nombre.like(nombre)).order_by(Item.nombre)[desde:hasta]
            return items
        else:
            total = session.query(Item).join(Fase).join(Proyecto).\
            filter(Proyecto.idproyecto== idproyecto).\
            filter(or_(nroFase-Fase.numero==1, nroFase - Fase.numero == 0)).\
            filter(Item.idestadoitem!=5).\
            filter(Item.nombre.like(nombre)).count()
            return total
     